﻿using CatClient.Message.Spi;
using CatClient.Message.Spi.Internals;
using CatClient.Util;
using System;
using System.Collections.Generic;

namespace CatClient.Message.Internals
{
    [Serializable]
    public class DefaultTransaction : AbstractMessage, ITransaction, IMessage
    {
        private IList<IMessage> _mChildren;

        private long _mDurationInMicro;

        protected string _contextKey;

        private IMessageManager _messageManager;

        public IList<IMessage> Children
        {
            get
            {
                IList<IMessage> arg_18_0;
                if ((arg_18_0 = this._mChildren) == null)
                {
                    arg_18_0 = (this._mChildren = new List<IMessage>());
                }
                return arg_18_0;
            }
        }

        public string ContextKey
        {
            get
            {
                return this._contextKey;
            }
        }

        public long DurationInMicros
        {
            get
            {
                if (this._mDurationInMicro >= 0L)
                {
                    return this._mDurationInMicro;
                }
                long result = 0L;
                int num = (this._mChildren == null) ? 0 : this._mChildren.Count;
                if (num > 0 && this._mChildren != null)
                {
                    IMessage message = this._mChildren[num - 1];
                    if (message is ITransaction)
                    {
                        ITransaction transaction = message as ITransaction;
                        result = transaction.Timestamp * 1000L + transaction.DurationInMicros - base.TimestampInMicros;
                    }
                    else
                    {
                        result = message.Timestamp * 1000L - base.TimestampInMicros;
                    }
                }
                return result;
            }
            set
            {
                this._mDurationInMicro = value;
            }
        }

        public long DurationInMillis
        {
            get
            {
                return this.DurationInMicros / 1000L;
            }
            set
            {
                this._mDurationInMicro = value * 1000L;
            }
        }

        public bool Standalone
        {
            get;
            set;
        }

        public DefaultTransaction(string type, string name, IMessageManager messageManager = null) : base(type, name, messageManager)
        {
            DefaultMessageManager expr_10 = (DefaultMessageManager)messageManager;
            this._contextKey = ((expr_10 != null) ? expr_10.CurrentContext.Key : null);
            this._messageManager = messageManager;
            this._mDurationInMicro = -1L;
            this.Standalone = true;
        }

        public ITransaction AddChild(IMessage message)
        {
            if (this._mChildren == null)
            {
                this._mChildren = new List<IMessage>();
            }
            if (message != null)
            {
                this._mChildren.Add(message);
            }
            else
            {
                Cat.GetProducer().LogError(new Exception("null child message"));
            }
            return this;
        }

        public override void Complete()
        {
            if (base.IsCompleted())
            {
                IMessage message = new DefaultEvent("CAT", "BadInstrument", null)
                {
                    Status = "TransactionAlreadyCompleted"
                };
                message.Complete();
                this.AddChild(message);
                return;
            }
            this._mDurationInMicro = MilliSecondTimer.CurrentTimeMicros - base.TimestampInMicros;
            base.SetCompleted(true);
            if (this._messageManager != null)
            {
                this._messageManager.End(this);
            }
        }

        public bool HasChildren()
        {
            return this._mChildren != null && this._mChildren.Count > 0;
        }
    }
}
